package com.zym.init.controller.backend;

import com.zym.init.core.annotation.ApiBackendRestController;
import com.zym.init.core.annotation.Log;
import com.zym.init.core.controller.BaseController;
import com.zym.init.core.domain.AjaxResult;
import com.zym.init.enums.UserStatusEnum;
import com.zym.init.model.po.UserPo;
import com.zym.init.model.query.UserQuery;
import com.zym.init.service.UserService;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

/**
 * 用户控制器
 *
 * @author ZouYangMing
 */
@Validated
@ApiBackendRestController
@RequestMapping(path = "/user", produces = "application/json")
@Tag(name = "01 用户", description = "API")
@ApiResponse(responseCode = "0", description = "成功")
public class UserController extends BaseController {

    final private UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    /**
     * 用户列表
     */
    @Log(title = "获取用户列表")
    @PreAuthorize("@ss.hasPermission('system:user:list')")
    @GetMapping
    public AjaxResult list(UserQuery query) {
        return success("获取成功", userService.getPage(query));
    }

    /**
     * 删除用户
     */
    @Log(title = "删除用户")
    @PreAuthorize("@ss.hasPermission('system:user:delete')")
    @DeleteMapping("/{userIds}")
    public AjaxResult delete(@PathVariable List<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return fail("用户ID不能为空");
        }
        if (userIds.contains(1L)) {
            return fail("不能删除默认管理员");
        }
        if (userIds.contains(getUserId())) {
            return error("不能删除自己的账号");
        }
        boolean isSuccess = userService.removeByIds(userIds);
        if (!isSuccess) {
            return fail("删除失败");
        }
        return success("删除成功");
    }

    /**
     * 新增用户
     */
    @Log(title = "新增用户")
    @PreAuthorize("@ss.hasPermission('system:user:add')")
    @PostMapping
    public AjaxResult add(@RequestBody @Validated(value = {UserQuery.Add.class}) UserQuery query) {
        if (!userService.add(query)) {
            return fail("新增失败");
        }
        return success("新增成功");
    }

    /**
     * 修改用户
     */
    @Log(title = "修改用户")
    @PreAuthorize("@ss.hasPermission('system:user:edit')")
    @PutMapping
    public AjaxResult edit(@RequestBody @Validated(value = {UserQuery.Update.class}) UserQuery query) {
        UserPo userPo = userService.getById(query.getUserId());
        userPo.setAvatar(query.getAvatar());
        userPo.setUserId(query.getUserId());
        userPo.setNickname(query.getNickname());
        userPo.setUsername(query.getUsername());
        userPo.setRoleList(query.getRoleList());
        userPo.setStatus(query.getStatus());
        // 如果用户状态为临时封禁，则必须设置临时封禁时间
        if (query.getStatus() != null &&UserStatusEnum.SUSPENDED.getStatus().equals(query.getStatus())) {
            if (query.getSuspendedTime() == null) {
                return fail("设置临时封禁状态，必须设置临时封禁时间");
            }
            if (query.getSuspendedTime().before(new Date())) {
                return fail("设置临时封禁时间必须大于当前时间");
            }
            userPo.setSuspendedTime(query.getSuspendedTime());
        }
        // 修改密码
        if (StringUtils.hasLength(query.getPassword())) {
            // 加密密码
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            String encryptedPassword = bCryptPasswordEncoder.encode(query.getPassword());
            userPo.setPassword(encryptedPassword);
        }
        // 不能修改默认管理员的用户名、状态、角色
        if (userPo.getUserId() == 1L) {
            userPo.setUsername(null);
            userPo.setStatus(null);
            userPo.setRoleList(null);
        }
        boolean isOk = userService.updateById(userPo);
        if (!isOk) {
            return fail("修改失败");
        }
        return success("修改成功");
    }
}
